#!/bin/env python

import ezpub
import ezp_cfg
from ezp_util import *
import glob
import os
import pdb
import pexpect
import re
import shutil
import signal
import socket
import stat
import sys
import testhelp
import unittest

from optparse import *

# ---------------------------------------------------------------------------
def main(args):
    p = OptionParser()
    p.add_option('-S', '--stdout',
                 action='store_true', default=False, dest='stdout',
                 help='show stdout of tests')
    p.add_option('-d', '--debug',
                 action='store_true', default=False, dest='debug',
                 help='run under the debugger')
    p.add_option('-k', '--keep',
                 action='store_true', default=False, dest='keep',
                 help='keep test files')
    p.add_option('-l', '--list',
                 action='store_true', default=False, dest='list',
                 help='list tests')
    p.add_option('-q', '--quiet',
                 action='store_true', default=False, dest='quiet',
                 help='quieter')
    p.add_option('-t', '--to',
                 action='store', default='', dest='final',
                 help='run all tests up to this one')
    p.add_option('-v', '--verbose',
                 action='store_true', default=False, dest='verbose',
                 help='louder')
    (o, a) = p.parse_args(args)
    
    if o.debug:
        pdb.set_trace()

    show_stdout(o.stdout)
    
    check_environment()
    setup_logging()
    
    for opt in ['-d', '--debug', '-S', '--stdout']:
        if opt in args:
            args.remove(opt)

    testhelp.main(args, 'Ezpub')

# ---------------------------------------------------------------------------
class EzpubSpawn(pexpect.spawn):
    """
    Here we subclass pexpect.spawn so we can do two things:

    1) check the value of show_stdout to decide how to set self.logfile,

    2) override expect() and add a check for Tracebacks each time
       expect() runs. This allows us to avoid sticking
       "assert('Traceback' not in S.before)" inline after every call
       to S.expect()

    Note that there are occasions when a traceback is expected as part
    of a test's successful output and we don't EzpubSpawn.expect to
    complain about it. For those cases, we've added catch_tb so we can
    tell expect NOT to catch the traceback.
    """
    def __init__(self, cmd, show_stdout):
        super(EzpubSpawn, self).__init__(cmd)
        if show_stdout:
            self.logfile = sys.stdout
        else:
            self.logfile = None

    def expect(self, pattern, catch_tb=True, timeout=-1,
               searchwindowsize=None):
        rc = super(EzpubSpawn, self).expect(pattern, timeout, searchwindowsize)
        if "Traceback" in self.before and catch_tb:
            raise AssertionError("Traceback detected")
        return rc
    
# ---------------------------------------------------------------------------
class Ezpub(unittest.TestCase):

    # -----------------------------------------------------------------------
    def test_us_valnum(self):
        """
        test_us_valnum: in userSelect(), each valid number should return
        corresponding string

        Expected outcome: number in range should return correct string
        """
        try:
            cmd = "ezpub generate --ustest 'testvalue," + ",".join(strings)
            for num in range(1, 6):
                S = spawn_ezpub(self, cmd)
                S.expect("Please select a testvalue > ")
                S.sendline("%d" % num)
                S.expect(pexpect.EOF)
                q = re.findall("val = (\S+)", S.before)
                assert(q[0] == strings[num-1])
        except:
            tlogger.info('%s * * * FAILED' % my_name())
            raise
        tlogger.info('%-25s PASSED' % my_name())
        
    # -----------------------------------------------------------------------
    def test_us_valstr(self):
        """
        test_us_valstr: in userSelect(), each valid string should get
        back itself

        Expected outcome: valid strings returns itself
        """
        try:
            cmd = "ezpub generate --ustest 'testvalue," + ",".join(strings)
            for str in strings:
                S = spawn_ezpub(self, cmd)
                S.expect("Please select a testvalue > ")

                S.sendline(str)
                S.expect(pexpect.EOF)
                q = re.findall("val = (\S+)", S.before)
                assert(q[0] == str)
        except:
            tlogger.info('%s * * * FAILED' % my_name())
            raise
        tlogger.info('%-25s PASSED' % my_name())

    # -----------------------------------------------------------------------
    def test_us_nvnum(self):
        """
        test_us_nvnum: in userSelect(), out of range numbers should reprompt

        Expected outcome: out of range number causes reprompt
        """
        try:
            oornums = [-1, 0, 6, 19, 1]
            cmd = "ezpub generate --ustest 'testvalue," + ",".join(strings)
            S = spawn_ezpub(self, cmd)
            while True:
                which = S.expect(["Please select a testvalue > ", pexpect.EOF])
                if which == 1:
                    if num != 1:
                        assert("Out of range numbers should reprompt" == "")
                    else:
                        break

                num = oornums.pop(0)
                S.sendline("%d" % num)
        except:
            tlogger.info('%s * * * FAILED' % my_name())
            raise
        tlogger.info('%-25s PASSED' % my_name())

    # -----------------------------------------------------------------------
    def test_us_nvstr(self):
        """
        test_us_nvstr: in userSelect(), invalid strings should reprompt

        Expected outcome: invalid string causes reprompt
        """
        try:
            lstrs = [x + "_x" for x in strings]
            lstrs.append(strings[0])

            cmd = "ezpub generate --ustest 'testvalue," + ",".join(strings)
            S = spawn_ezpub(self, cmd)
            while True:
                which = S.expect(["Please select a testvalue > ", pexpect.EOF])
                if which == 1:
                    if choice != strings[0]:
                        assert("Invalid string should reprompt" == "")
                    else:
                        break

                choice = lstrs.pop(0)
                S.sendline(choice)
        except:
            tlogger.info('%s * * * FAILED' % my_name())
            raise
        tlogger.info('%-25s PASSED' % my_name())

    # -----------------------------------------------------------------------
    def test_interruptible_input(self):
        """
        test_interruptible_input: Verify that a SIGINT will interrupt an
        input request without a traceback.

        Expected outcome: at SIGINT program exits without traceback
        """
        try:
            S = spawn_ezpub(self, "ezpub generate")
            S.expect(r"Input path\? \[\.\] > ")
            S.kill(signal.SIGINT)
            S.expect(pexpect.EOF)
            expected = "[user abort]\r\n"
            if S.before != expected:
                print("expected: '%s' (%d)" % (expected, len(expected)))
                print("  actual: '%s' (%d)" % (S.before, len(S.before)))
                print("post signal output: '%s'" % S.before)
                assert(False)
        except:
            tlogger.info('%s * * * FAILED' % my_name())
            raise
        tlogger.info('%-25s PASSED' % my_name())

    # -----------------------------------------------------------------------
    def test_disclaimer_no(self):
        """
        test_disclaimer_no: respond non-yes to staging disclaimer

        Expected outcome: program should exit
        """
        try:
            dirname = eg_data_dir('cmip5')
            xmlname = eg_xml('disno.xml')
            make_dummy_xml(xmlname)

            cmd = "ezpub stage -i %s -t %s" % (dirname, xmlname)
            S = spawn_ezpub(self, cmd)
            which = S.expect([" > ", pexpect.EOF, pexpect.TIMEOUT])
            if 0 == which:
                S.sendline("anything but yes")
                S.expect(pexpect.EOF)
                assert("Exiting..." in S.before)
            elif 1 == which:
                assert("" ==
                       "ezpub should have prompted for disclaimer confirmation")
            elif 2 == which:
                assert("Unexpected output" == "")

            os.unlink(xmlname)
        except:
            tlogger.info('%s * * * FAILED' % my_name())
            raise
        tlogger.info('%-25s PASSED' % my_name())

    # -----------------------------------------------------------------------
    def test_disclaimer_yes(self):
        """
        test_disclaimer_yes: respond yes to staging disclaimer

        Expected outcome: program should attempt to stage
        """
        try:
            dirname = eg_data_dir("cmip5")
            xmlname = eg_xml("foo.xml")
            touch(xmlname)
            make_app_prop(datasrc=dirname)

            cmd = "ezpub stage -i %s -t %s" % (dirname, xmlname)
            S = spawn_ezpub(self, cmd)
            which = S.expect([pexpect.EOF, " > ", pexpect.TIMEOUT])

            if 0 == which:
                os.unlink(xmlname)
                self.fail("ezpub should have prompted for disclaimer confirmation")
            elif 1 == which:
                S.sendline("yes")
                S.expect("PASSCODE:")
                assert("globus-url-copy" in S.before)
                S.kill(signal.SIGINT)
                os.unlink(xmlname)
            elif 2 == which:
                os.unlink(xmlname)
                self.fail("Unanticipated output")
        except:
            tlogger.info('%s * * * FAILED' % my_name())
            raise
        tlogger.info('%-25s PASSED' % my_name())

    # ----------------------------------------------------------------------
    def test_disclaimer_YES(self):
        """
        test_disclaimer_YES: respond YES to staging disclaimer

        Expected outcome: program should attempt to stage
        """
        try:
            dirname = eg_data_dir("test")
            xmlname = eg_xml("foo.xml")
            touch(xmlname)
            make_app_prop(datasrc=dirname)

            cmd = "ezpub stage -i %s -t %s" % (dirname, xmlname)
            S = spawn_ezpub(self, cmd)
            which = S.expect([pexpect.EOF, " > ", pexpect.TIMEOUT])

            if 0 == which:
                os.unlink(xmlname)
                self.fail("ezpub should have prompted for disclaimer confirmation")
            elif 1 == which:
                S.sendline("YES")
                S.expect('PASSCODE:')
                assert("globus-url-copy" in S.before)
                S.kill(signal.SIGINT)
                os.unlink(xmlname)
            elif 2 == which:
                os.unlink(xmlname)
                self.fail("Unanticipated output")
        except:
            tlogger.info('%s * * * FAILED' % my_name())
            raise
        tlogger.info('%-25s PASSED' % my_name())

    # ----------------------------------------------------------------------
    def test_ezpub_py(self):
        """
        test_ezpub_py: test command 'ezpub.py'
        """
        try:
            cmd = "ezpub.py"
            S = spawn_ezpub(self, cmd)
            S.expect(pexpect.EOF)
            assert("Type 'ezpub <subcommand>' to run one of the following commands"
                   in S.before)
            d = dir(sys.modules["ezpub"])
            for item in d:
                if item.startswith("ez_"):
                    assert("%s - " % item[3:] in S.before)
        except:
            tlogger.info('%s * * * FAILED' % my_name())
            raise
        tlogger.info('%-25s PASSED' % my_name())

    # ----------------------------------------------------------------------
    def test_help(self):
        """
        test_help: test 'ezpub help'
        """
        try:
            cmd = "ezpub help"
            S = spawn_ezpub(self, cmd)
            S.expect(pexpect.EOF)
            assert("Type 'ezpub <subcommand>' to run one of the following commands"
                   not in S.before)
            assert("help - show this list" in S.before)
            d = dir(sys.modules["ezpub"])
            for item in d:
                if item.startswith("ez_"):
                    assert("%s - " % item[3:] in S.before)
        except:
            tlogger.info('%s * * * FAILED' % my_name())
            raise
        tlogger.info('%-25s PASSED' % my_name())

    # ----------------------------------------------------------------------
    def test_help_help(self):
        """
        test_help_help: test 'ezpub help help'
        """
        try:
            cmd = "ezpub help help"
            S = spawn_ezpub(self, cmd)
            S.expect(pexpect.EOF)
            assert("help - show this list" in S.before)
            assert("list of functions" in  S.before)
            assert("generate - produce a THREDDS catalog" not in S.before)
        except:
            tlogger.info('%s * * * FAILED' % my_name())
            raise
        tlogger.info('%-25s PASSED' % my_name())

    # ----------------------------------------------------------------------
    def test_help_cleanup(self):
        """
        test_help_cleanup: test 'ezpub help cleanup'
        """
        try:
            cmd = "ezpub help cleanup"
            S = spawn_ezpub(self, cmd)
            S.expect(pexpect.EOF)
            assert("cleanup - remove work files created by publish requests"
                   in S.before)
            assert("help - show this list" not in S.before)
            assert("usage: ezpub cleanup [--dry-run/-n] [--dir/-D <dir>]"
                   in S.before)
        except:
            tlogger.info('%s * * * FAILED' % my_name())
            raise
        tlogger.info('%-25s PASSED' % my_name())

    # ----------------------------------------------------------------------
    def test_help_generate(self):
        """
        test_help_generate: test 'ezpub help generate'
        """
        try:
            cmd = "ezpub help generate"
            S = spawn_ezpub(self, cmd)
            S.expect(pexpect.EOF)
            assert("generate - collect metadata from .nc/.cdf files" in S.before)
            assert("help - show this list" not in S.before)
            assert("usage: ezpub generate -i" in S.before)
        except:
            tlogger.info('%s * * * FAILED' % my_name())
            raise
        tlogger.info('%-25s PASSED' % my_name())

    # ----------------------------------------------------------------------
    def test_help_stage(self):
        """
        test_help_stage: test 'ezpub help stage'
        """
        try:
            cmd = "ezpub help stage"
            S = spawn_ezpub(self, cmd)
            S.expect(pexpect.EOF)
            assert("stage - copy files to datanode" in S.before)
            assert("help - show this list" not in S.before)
            assert("usage: ezpub stage -" in S.before)
        except:
            tlogger.info('%s * * * FAILED' % my_name())
            raise
        tlogger.info('%-25s PASSED' % my_name())

    # ----------------------------------------------------------------------
    def test_help_publish(self):
        """
        test_help_publish: test 'ezpub help publish'
        """
        try:
            cmd = "ezpub help publish"
            S = spawn_ezpub(self, cmd)
            S.expect(pexpect.EOF)
            assert("publish - make data available for public downloading"
                   in S.before)
            assert("help - show this list" not in S.before)
            assert("usage: ezpub publish" in S.before)
        except:
            tlogger.info('%s * * * FAILED' % my_name())
            raise
        tlogger.info('%-25s PASSED' % my_name())

    # ----------------------------------------------------------------------
    def test_help_localpub(self):
        """
        test_help_localpub: test 'ezpub help localpub'
        """
        try:
            cmd = "ezpub help localpub"
            S = spawn_ezpub(self, cmd)
            S.expect(pexpect.EOF)
            assert("localpub - publish data to the local node, without staging"
                   in S.before)
            assert("help - show this list" not in S.before)
            assert("usage: ezpub localpub -i <input-dir> -p <project>"
                   in S.before)
        except:
            tlogger.info('%s * * * FAILED' % my_name())
            raise
        tlogger.info('%-25s PASSED' % my_name())

    # ----------------------------------------------------------------------
    def test_help_unpublish_test(self):
        """
        test_help_unpublish: test 'ezpub help unpublish'
        """
        try:
            cmd = "ezpub help unpublish"
            S = spawn_ezpub(self, cmd)
            S.expect(pexpect.EOF)
            assert("unpublish - make files unavailable for public downloading"
                   in S.before)
            assert("help - show this list" not in S.before)
            assert("usage: ezpub unpublish" in S.before)
        except:
            tlogger.info('%s * * * FAILED' % my_name())
            raise
        tlogger.info('%-25s PASSED' % my_name())

    # ----------------------------------------------------------------------
    def test_help_localunpub_test(self):
        """
        test_help_localunpub: test 'ezpub help localunpub'
        """
        try:
            cmd = "ezpub help localunpub"
            S = spawn_ezpub(self, cmd)
            S.expect(pexpect.EOF)
            assert("localunpub - unpublish data on the local node"
                   in S.before)
            assert("help - show this list" not in S.before)
            assert("usage: ezpub localunpub -x <xmlfile>" in S.before)
        except:
            tlogger.info('%s * * * FAILED' % my_name())
            raise
        tlogger.info('%-25s PASSED' % my_name())

    # ----------------------------------------------------------------------
    def test_help_unknown(self):
        """
        test_help_unknown: help for unknown subcommand
        """
        try:
            cmd = "ezpub help zorro"
            S = spawn_ezpub(self, cmd)
            S.expect(pexpect.EOF)
            assert("Subcommand 'zorro' not recognized" in S.before)
            assert("generate - collect" in S.before)
            assert("help - show" in S.before)
        except:
            tlogger.info('%s * * * FAILED' % my_name())
            raise
        tlogger.info('%-25s PASSED' % my_name())

    # ----------------------------------------------------------------------
    def test_mklink_bin(self):
        """
        test_mklink_bin: verify that 'bin/ezpub.py -L' makes link
        bin/ezpub => ./ezpub.py
        """
        try:
            if not os.path.exists("ezpub.py"):
                self.fail("ezpub.py does not exist")

            if os.path.exists("./bin"):
                shutil.rmtree("./bin")

            os.mkdir("./bin")
            shutil.copy2("./ezpub.py", "./bin")

            S = spawn_ezpub(self, "./bin/ezpub.py -L")
            S.expect(pexpect.EOF)
            assert("creating symlink:" in S.before)
            assert(os.path.islink("./bin/ezpub"))
            S = spawn_ezpub(self, "./bin/ezpub help")
            S.expect(pexpect.EOF)
            for subcmd in ["cleanup", "generate", "help", "publish",
                           "stage", "unpublish"]:
                assert("%s - " % subcmd in S.before)
        except:
            tlogger.info('%s * * * FAILED' % my_name())
            raise
        tlogger.info('%-25s PASSED' % my_name())

    # ----------------------------------------------------------------------
    def test_mklink_noL(self):
        """
        test_mklink_noL: ezpub.py called without -L when ezpub does not exist

        Expected outcome: create symlink ezpub -> ezpub.py
        """
        try:
            if not os.path.exists("ezpub.py"):
                self.fail("ezpub.py does not exist")

            if os.path.exists("./bin"):
                shutil.rmtree("./bin")

            os.mkdir("./bin")
            shutil.copy2("./ezpub.py", "./bin")

            S = spawn_ezpub(self, "./bin/ezpub.py")
            S.expect(pexpect.EOF)
            assert("creating symlink:" not in S.before)
            assert(not os.path.exists("./bin/ezpub"))
        except:
            tlogger.info('%s * * * FAILED' % my_name())
            raise
        tlogger.info('%-25s PASSED' % my_name())

    # ----------------------------------------------------------------------
    def test_mklink(self):
        """
        test_mklink: verify that 'ezpub.py -L' creates link ezpub => ezpub.py
        """
        try:
            if not os.path.exists("ezpub.py"):
                self.fail("ezpub.py does not exist")

            if os.path.islink("ezpub"):
                os.unlink("ezpub")

            S = spawn_ezpub(self, "ezpub.py -L")
            S.expect(pexpect.EOF)
            assert("creating symlink:" in S.before)
            assert(os.path.islink("ezpub"))
        except:
            tlogger.info('%s * * * FAILED' % my_name())
            raise
        tlogger.info('%-25s PASSED' % my_name())

    # -----------------------------------------------------------------------
    def test_pclok(self):
        """
        test_pclok: A good project is specified on the command line

        No project in the input.

        Expected outcome: generate a thredds file.
        """
        try:
            scigest_build_check(self)
            project = 'test'
            section = 'project:%s' % project
            input_dir = eg_data_dir(project)
            cmd = "ezpub generate --project %s --input %s" % (project, input_dir)
            cfg = ezp_cfg.loadConfig("./esg.ini")
            cfg.set(section, 'project', project)
            S = spawn_ezpub(self, cmd)
            S.expect(pexpect.EOF)
            self.verify_generation(S, input_dir, project)
        except:
            tlogger.info('%s * * * FAILED' % my_name())
            raise
        tlogger.info('%-25s PASSED' % my_name())

    # ----------------------------------------------------------------------
    def test_pclbad(self):
        """
        test_pclbad: An invalid project is specified on the command line

        No project in the input.

        Expected outcome: error message.
        """
        try:
            cmd = "ezpub generate --project aardvark"
            S = spawn_ezpub(self, cmd)
            S.expect(r"Input path\? \[\.\] > ")
            S.sendline(eg_data_dir('test'))
            S.expect(pexpect.EOF, catch_tb=False)
            assert("Project 'aardvark' is not recognized" in S.before)
        except:
            tlogger.info('%s * * * FAILED' % my_name())
            raise
        tlogger.info('%-25s PASSED' % my_name())

    # ----------------------------------------------------------------------
    def test_listproj(self):
        """
        test_listproj: list_projects should get a list of projects

        Expected outcome: list of projects from esg.ini
        """
        try:
            cmd = "ezpub list_projects"
            projlist = ezp_cfg.project_list()
            S = spawn_ezpub(self, cmd)
            S.expect(pexpect.EOF)
            assert("Available Projects:" in S.before)
            for p in projlist:
                assert(p in S.before)

            cmd = "ezpub list_projects"
            S = spawn_ezpub(self, cmd)
            S.expect(pexpect.EOF)
            assert("Available Projects:" in S.before)
            for p in projlist:
                assert(p in S.before)
        except:
            tlogger.info('%s * * * FAILED' % my_name())
            raise
        tlogger.info('%-25s PASSED' % my_name())

    # ----------------------------------------------------------------------
    def test_ppr(self):
        """
        test_ppr: No project on command line. Prompt.

        Expected outcome: user is prompted to select a project.
        """
        try:
            datadir = eg_data_dir('test')
            cmd = "ezpub generate --input %s" % datadir
            S = spawn_ezpub(self, cmd)
            S.expect("Please select a project > ")
            assert("project:" in S.before)
            assert("1." in S.before)
            S.kill(signal.SIGINT)
            S.expect(pexpect.EOF)
        except:
            tlogger.info('%s * * * FAILED' % my_name())
            raise
        tlogger.info('%-25s PASSED' % my_name())

    # ----------------------------------------------------------------------
    def test_cdf(self):
        """
        test_cdf: Handle .cdf files.

        Expected outcome: thredds file generated
        """
        try:
            scigest_build_check(self)
            project = "arm"
            input_dir = eg_data_dir(project)
            cmd = "ezpub generate --input %s" % input_dir
            S = spawn_ezpub(self, cmd)
            which = S.expect([pexpect.EOF, "Please select a project > "])
            if which == 0:
                self.fail("ezpub should have prompted for a project")
            S.sendline("arm")
            S.expect(pexpect.EOF)
            self.verify_generation(S, input_dir, project)
        except:
            tlogger.info('%s * * * FAILED' % my_name())
            raise
        tlogger.info('%-25s PASSED' % my_name())

    # -----------------------------------------------------------------------
    def test_cdf_nc(self):
        """
        test_cdf_nc: Handle both .cdf and .nc files in the same run.

        Expected outcome: thredds file generated
        """
        try:
            scigest_build_check(self)
            project = "arm"
            input_dir = eg_data_dir(project)
            cmd = "ezpub generate --input %s" % input_dir
            S = spawn_ezpub(self, cmd)
            which = S.expect([pexpect.EOF, "Please select a project > "])
            if which == 0:
                self.fail("ezpub should have prompted for a project")
            S.sendline(project)
            S.expect(pexpect.EOF)
            self.verify_generation(S, input_dir, project)
        except:
            tlogger.info('%s * * * FAILED' % my_name())
            raise
        tlogger.info('%-25s PASSED' % my_name())

    # ----------------------------------------------------------------------
    def test_input_noarg(self):
        """
        test_input_noarg: Option --input is present with no argument

        Expected outcome: usage/error message
        """
        try:
            cmd = "ezpub generate --input"
            S = spawn_ezpub(self, cmd)
            S.expect(pexpect.EOF)
            assert("sage: ezpub [options]" in S.before)
            assert("ezpub: error: --input option requires an argument" in S.before)
        except:
            tlogger.info('%s * * * FAILED' % my_name())
            raise
        tlogger.info('%-25s PASSED' % my_name())

    # ------------------------------------------------------------------------
    def test_ppr_pok(self):
        """
        test_ppr_pok: No proj on command line. Prompt. Provide a valid
        project

        Expected outcome: thredds file generated
        """
        try:
            scigest_build_check(self)
            project = "clm_input"
            input_dir = eg_data_dir(project)
            dirbase = os.path.basename(input_dir)
            cmd = "ezpub generate --input %s" % input_dir
            S = spawn_ezpub(self, cmd)
            which = S.expect([pexpect.EOF, "Please select a project > "])
            if which == 0:
                F.fail("ezpub should have prompted for a project")

            S.sendline(project)
            S.expect(pexpect.EOF)
            xmlpath = "%s/.scigest/output/1/%s_%s.xml" % (home(),
                                                          project,
                                                          dirbase)
            assert("java -Dproperties.location" in S.before)
            assert("Processing directory" in S.before)
            assert("Generating catalog file" in S.before)
            assert(os.path.exists(xmlpath))
            assert(datafiles_in_xml(input_dir, xmlpath))
        except:
            tlogger.info('%s * * * FAILED' % my_name())
            raise
        tlogger.info('%-25s PASSED' % my_name())

    # -----------------------------------------------------------------------
    def test_idclnonx(self):
        """
        test_idclnonx: A non-existent directory is specified on the
        command line for input

        Expected outcome: error message
        """
        try:
            input_dir = eg_data_dir("frooble")
            cmd = "ezpub generate --input %s" % input_dir
            S = spawn_ezpub(self, cmd)
            S.expect(pexpect.EOF, catch_tb=False)
            assert("'%s' is not a directory." % input_dir in S.before)
        except:
            tlogger.info('%s * * * FAILED' % my_name())
            raise
        tlogger.info('%-25s PASSED' % my_name())

    # -----------------------------------------------------------------------
    def test_idclok(self):
        """
        test_idclok: A valid directory is specified on the command line
        for input

        Expected outcome: input directory is used, prompt for project.
        """
        try:
            project = "arm"
            input_dir = eg_data_dir(project)
            cmd = "ezpub generate --input %s" % input_dir
            S = spawn_ezpub(self, cmd)
            which = S.expect([pexpect.EOF, "Please select a project > "])
            if which == 0:
                F.fail("ezpub should have prompted for a project")
            elif which == 1:
                S.kill(signal.SIGINT)
                S.expect(pexpect.EOF)
        except:
            tlogger.info('%s * * * FAILED' % my_name())
            raise
        tlogger.info('%-25s PASSED' % my_name())

    # -----------------------------------------------------------------------
    def test_idclunr(self):
        """
        test_idclunr: An unreadable directory is specified on the command line
        for input

        Expected outcome: error message
        """
        try:
            unrdir  = eg_data_dir("unreadable")
            if not os.path.exists(unrdir):
                os.mkdir(unrdir)
            if os.access(unrdir, os.R_OK):
                os.chmod(unrdir, 0000)
            cmd = "ezpub generate --input %s" % unrdir
            S = spawn_ezpub(self, cmd)
            S.expect(pexpect.EOF, catch_tb=False)
            os.rmdir(unrdir)
            assert("Directory '%s' is not readable" % unrdir in S.before)
        except:
            tlogger.info('%s * * * FAILED' % my_name())
            raise
        tlogger.info('%-25s PASSED' % my_name())

    # -----------------------------------------------------------------------
    def test_idprnonx(self):
        """
        test_idprnonx: A non-existent directory is provided to the prompt

        Expected outcome: error message
        """
        try:
            cmd = "ezpub generate"
            nonxdir = eg_data_dir("nosuchdir")
            S = spawn_ezpub(self, cmd)
            S.expect(r"Input path\? \[\.\] > ")
            S.sendline(nonxdir)
            S.expect(pexpect.EOF, catch_tb=False)
            assert("'%s' is not a directory" % nonxdir in S.before)
        except:
            tlogger.info('%s * * * FAILED' % my_name())
            raise
        tlogger.info('%-25s PASSED' % my_name())

    # -----------------------------------------------------------------------
    def test_zpub_cleanup(self):
        """
        test_zpub_cleanup: Cleanup $HOME/.scigest

        Expected outcome: $HOME/.scigest should be cleaned up
        """
        try:
            # this is the list of things to be removed
            flist = ['catalog.txt', 'application.properties']
            flist.extend([os.path.basename(x)
                          for x in glob.glob("%s/.scigest/copylist*.txt"
                                             % home())])
            for (dir, dl, fl) in os.walk("%s/.scigest/output" % home, False):
                for fn in fl:
                    flist.append(fn)

            # except for these
            rlist = ["catalog.xml", "my.properties", "my.properties~"]
            for item in rlist:
                if item in flist: flist.remove(item)

            cmd = "ezpub cleanup"
            S = spawn_ezpub(self, cmd)
            S.expect(pexpect.EOF)
            for item in flist:
                self.assertEqual(item in S.before, True)
                if os.path.exists("%s/.scigest/%s" % (home(), item)):
                    self.fail("%s/.scigest/%s exists and should not"
                              % (home(), item))
        except:
            tlogger.info('%s * * * FAILED' % my_name())
            raise
        tlogger.info('%-25s PASSED' % my_name())

    # -----------------------------------------------------------------------
    def test_zzz_cleanup(self):
        """
        test_zzz_cleanup: Cleanup $HOME/.scigest when it's already clean

        Expected outcome: message -- 'Nothing to clean up.'
        """
        try:
            cmd = "ezpub cleanup"
            S = spawn_ezpub(self, cmd)
            S.expect(pexpect.EOF)
            assert("Nothing to clean up." in S.before)
        except:
            tlogger.info('%s * * * FAILED' % my_name())
            raise
        tlogger.info('%-25s PASSED' % my_name())

    # ------------------------------------------------------------------------
    def test_idprok(self):
        """
        test_idprok: A valid directory is provided to the prompt
        for input

        No project in input

        Expected outcome: thredds file produced
        """
        try:
            scigest_build_check(self)
            project = 'clm_input'
            section = 'project:%s' % project
            input_dir = eg_data_dir(project)
            cmd = "ezpub generate --project clm_input"
            cfg = ezp_cfg.loadConfig("./esg.ini")
            cfg.set(section, 'project', project)
            S = spawn_ezpub(self, cmd)
            S.expect(r"Input path\? \[\.\] > ")
            S.sendline(input_dir)
            S.expect(pexpect.EOF)
            self.verify_generation(S, input_dir, project)
        except:
            tlogger.info('%s * * * FAILED' % my_name())
            raise
        tlogger.info('%-25s PASSED' % my_name())

    # -----------------------------------------------------------------------
    def test_idprunr(self):
        """
        test_idprunr: An unreadable directory is provided to the prompt

        Expected outcome: error message
        """
        try:
            unrdir = eg_data_dir("unreadable")
            if not os.path.exists(unrdir):
                os.mkdir(unrdir)
            if os.access(unrdir, os.R_OK):
                os.chmod(unrdir, 0000)
            cmd = "ezpub generate"
            S = spawn_ezpub(self, cmd)
            S.expect(r"Input path\? \[\.\] > ")
            S.sendline(unrdir)
            S.expect(pexpect.EOF, catch_tb=False)
            os.rmdir(unrdir)
            assert("Directory '%s' is not readable" % unrdir in S.before)
        except:
            tlogger.info('%s * * * FAILED' % my_name())
            raise
        tlogger.info('%-25s PASSED' % my_name())

    # -----------------------------------------------------------------------
    def txst_ifclnonx(self):
        """
        test_ifclnonx: A non-existent file is specified on the command line
        for input

        A non-existent file is the same as a non-existent directory, which
        we already test for. No need to complete this test. Note that this
        test is disabled by misspelling "test" in the name of the method.
        """
        pass

    # -----------------------------------------------------------------------
    def test_ifclok(self):
        """
        test_ifclok: A valid file is specified on the command line
        for input

        No project specified in the input file

        Expected outcome: failure that input is not a dir
        """
        try:
            input_dir = eg_data_dir("arm")
            filename = "nsacmbe_atm_v1.0_C1.c1.20010101.000000.cdf"
            inpath = "%s/%s" % (input_dir, filename)
            cmd = "ezpub generate --input %s" % inpath

            S = spawn_ezpub(self, cmd)
            S.expect(pexpect.EOF, catch_tb=False)
            assert("'%s' is not a directory" % inpath)
        except:
            tlogger.info('%s * * * FAILED' % my_name())
            raise
        tlogger.info('%-25s PASSED' % my_name())

    # ------------------------------------------------------------------------
    def test_ifclunr(self):
        """
        test_ifclunr: An unreadable file is specified on the command line
        for input

        Expected outcome: error message
        """
        try:
            unrfile = eg_data_dir("unrfile")
            if not os.path.exists(unrfile):
                open(unrfile, "w").close()
            if os.access(unrfile, os.R_OK):
                os.chmod(unrfile, 0000)
            cmd = "ezpub generate --input %s" % unrfile
            S = spawn_ezpub(self, cmd)
            S.expect(pexpect.EOF, catch_tb=False)
            os.unlink(unrfile)
            assert("'%s' is not a directory" % unrfile in S.before)
        except:
            tlogger.info('%s * * * FAILED' % my_name())
            raise
        tlogger.info('%-25s PASSED' % my_name())

    # ------------------------------------------------------------------------
    def txst_ifprnonx(self):
        """
        txst_ifprnonx_test: A non-existent file is provided to the prompt

        A non-existent file is the same as a non-existent directory, which
        we already test for. No need to complete this test.

        Note that this test is disabled by misspelling 'test' in the
        method name.
        """
        pass

    # ------------------------------------------------------------------------
    def test_ifprunr(self):
        """
        test_ifprunr: An unreadable file is provided to the input prompt

        Expected outcome: error message
        """
        try:
            unrfile = eg_data_dir("unrfile")
            if not os.path.exists(unrfile):
                open(unrfile, "w").close()
            if os.access(unrfile, os.R_OK):
                os.chmod(unrfile, 0000)
            cmd = "ezpub generate"
            S = spawn_ezpub(self, cmd)
            S.expect(r"Input path\? \[\.\] > ")
            S.sendline(unrfile)
            S.expect(pexpect.EOF, catch_tb=False)
            os.unlink(unrfile)
            assert("'%s' is not a directory" % unrfile in S.before)
        except:
            tlogger.info('%s * * * FAILED' % my_name())
            raise
        tlogger.info('%-25s PASSED' % my_name())

    # -----------------------------------------------------------------------
    def test_stage_idempty(self):
        """
        test_stage_idempty: -i argument is an empty directory

        Expected outcome: error message before disclaimer
        """
        try:
            mtdir = eg_data_dir("mtdir")
            xmlname = eg_xml("stidmt.xml")
            make_dir_xml(mtdir, xmlname)

            cmd = "ezpub stage -i %s -t %s" % (mtdir, xmlname)
            S = spawn_ezpub(self, cmd)
            which = S.expect([pexpect.EOF, "Any other response will terminate"],
                             catch_tb=False)
            remove_dir_xml(mtdir, xmlname)

            if 0 == which:
                assert("No data files found in directory '%s'" % mtdir in S.before)
            elif 1 == which:
                self.fail("Should have issued error before disclaimer")
            else:
                self.fail("Something unexpected happened")
        except:
            tlogger.info('%s * * * FAILED' % my_name())
            raise
        tlogger.info('%-25s PASSED' % my_name())

    # -----------------------------------------------------------------------
    def test_stage_ifnotnccdf(self):
        """
        stage_ifnotnccdf_test: -i argument is a file, not .nc, not .cdf

        Expected outcome: error message before disclaimer
        """
        try:
            dirname = eg_data_dir("notadir")
            xmlname = eg_xml("stifnn.xml")
            open(dirname, 'w').close
            make_dummy_xml(xmlname)

            cmd = "ezpub stage -i %s -t %s" % (dirname, xmlname)
            S = spawn_ezpub(self, cmd)
            which = S.expect([pexpect.EOF, "Any other response will terminate"],
                             catch_tb=False)

            os.unlink(dirname)
            os.unlink(xmlname)

            if 0 == which:
                assert("'%s' is not a directory." % dirname
                       in S.before)
            elif 1 == which:
                self.fail("Should have issued error before disclaimer")
            else:
                self.fail("Somthing unexpected happened")
        except:
            tlogger.info('%s * * * FAILED' % my_name())
            raise
        tlogger.info('%-25s PASSED' % my_name())

    # -----------------------------------------------------------------------
    def test_stage_inonexist(self):
        """
        test_stage_inonexist: -i argument does not exist

        Expected outcome: error message before disclaimer
        """
        try:
            dirname = eg_data_dir("nosuchdir")
            xmlname = eg_xml("stifx.xml")

            cmd = "ezpub stage -i %s -t %s" % (dirname, xmlname)
            S = spawn_ezpub(self, cmd)
            which = S.expect([pexpect.EOF, "Any other response will terminate"],
                             catch_tb=False)
            if 0 == which:
                assert("'%s' is not a directory." % dirname
                       in S.before)
            elif 1 == which:
                self.fail("Should have issued error before disclaimer")
            else:
                self.fail("Somthing unexpected happened")
        except:
            tlogger.info('%s * * * FAILED' % my_name())
            raise
        tlogger.info('%-25s PASSED' % my_name())

    # -----------------------------------------------------------------------
    def test_gen_ideepdir(self):
        """
        test_gen_ideepdir: -i directory has data files lower than top level

        Expected outcome: find the data files, generate thredds file
        """
        try:
            scigest_build_check(self)
            dirname = eg_data_dir("cmip5")
            project = "test"
            cmd = "ezpub generate -i %s -p %s" % (dirname, project)
            S = spawn_ezpub(self, cmd)
            S.expect(pexpect.EOF)
            self.verify_generation(S, dirname, project, "observations")
        except:
            tlogger.info('%s * * * FAILED' % my_name())
            raise
        tlogger.info('%-25s PASSED' % my_name())

    # -----------------------------------------------------------------------
    def test_stage_ideepdir(self):
        """
        test_stage_ideepdir: -i directory has data files lower than top level

        Expected outcome: find the data files, prompt for disclaimer confirm
        """
        try:
            dirname = eg_data_dir("cmip5")
            xmlname = eg_xml("stid.xml")
            make_dummy_xml(xmlname)

            cmd = "ezpub stage -i %s -t %s" % (dirname, xmlname)
            S = spawn_ezpub(self, cmd)
            which = S.expect([pexpect.EOF, "Any other response will terminate"],
                             catch_tb=False)
            if 0 == which:
                self.fail("Expected to see the prompt for disclaimer confirm")
            elif 1 == which:
                S.kill(signal.SIGINT)
                S.expect(pexpect.EOF)
            else:
                self.fail("Somthing unexpected happened")
        except:
            tlogger.info('%s * * * FAILED' % my_name())
            raise
        tlogger.info('%-25s PASSED' % my_name())

    # -----------------------------------------------------------------------
    def test_stage_tnonexist(self):
        """
        test_stage_tnonexist: -t argument does not exist

        Expected outcome: error message before disclaimer
        """
        try:
            dirname = eg_data_dir("c-lamp")
            xmlname = eg_xml("nosuchfile.xml")

            cmd = "ezpub stage -i %s -t %s" % (dirname, xmlname)
            S = spawn_ezpub(self, cmd)
            which = S.expect([pexpect.EOF, "Any other response will terminate"],
                             catch_tb=False)
            if 0 == which:
                assert("'%s' does not exist." % xmlname in S.before)
            elif 1 == which:
                self.fail("Should have issued error before disclaimer")
            else:
                self.fail("Something unexpected happened")
        except:
            tlogger.info('%s * * * FAILED' % my_name())
            raise
        tlogger.info('%-25s PASSED' % my_name())

    # -----------------------------------------------------------------------
    def test_stage_tisdir(self):
        """
        test_stage_tisdir: -t argument is a directory (should be .xml file)

        Expected outcome: error message before disclaimer
        """
        try:
            dirname = eg_data_dir('test')
            xmlname = eg_xml('dir.xml')
            safe_mkdir(xmlname)

            cmd = "ezpub stage -i %s -t %s" % (dirname, xmlname)
            S = spawn_ezpub(self, cmd)
            which = S.expect([pexpect.EOF, "Any other response will terminate"],
                             catch_tb=False)
            if 0 == which:
                assert("'%s' is a directory. -t expects an XML file." % xmlname
                       in S.before)
                os.rmdir(xmlname)
            elif 1 == which:
                os.rmdir(xmlname)
                self.fail("Should have issued error before disclaimer")
            else:
                os.rmdir(xmlname)
                self.fail("Something unexpected happened")
        except:
            tlogger.info('%s * * * FAILED' % my_name())
            raise
        tlogger.info('%-25s PASSED' % my_name())

    # ------------------------------------------------------------------------
    def test_stage_tfnotxml(self):
        """
        test_stage_tfnotxml: -t argument is a non-xml file

        Expected outcome: error message before disclaimer
        """
        try:
            dirname = eg_data_dir('cmip5')
            xmlname = eg_xml("foobar")
            touch(xmlname)

            cmd = "ezpub stage -i %s -t %s" % (dirname, xmlname)
            S = spawn_ezpub(self, cmd)
            which = S.expect([pexpect.EOF, "Any other response will terminate"],
                             catch_tb=False)
            if 0 == which:
                assert("'%s' is not an XML file." % xmlname in S.before)
                os.unlink(xmlname)
            elif 1 == which:
                os.unlink(xmlname)
                self.fail("Should have issued error before disclaimer")
            else:
                os.unlink(xmlname)
                self.fail("Something unexpected happened")
        except:
            tlogger.info('%s * * * FAILED' % my_name())
            raise
        tlogger.info('%-25s PASSED' % my_name())

    # ------------------------------------------------------------------------
    def test_badsgh_cleanup(self):
        """
        test_badsgh_cleanup: 'ezpub cleanup' with $SCIGEST_HOME set wrongly

        Expected outcome: $HOME/.scigest cleaned up
        """
        try:
            save_sgh = os.environ['SCIGEST_HOME']
            os.environ['SCIGEST_HOME'] = "/no/such/dir"

            # this is the list of things to be removed
            flist = [os.path.basename(x)
                     for x in glob.glob("%s/.scigest/*" % home())]

            # except for these
            rlist = ["catalog.xml", "my.properties", "my.properties~"]
            for item in rlist:
                if item in flist: flist.remove(item)

            cmd = "ezpub cleanup"
            S = spawn_ezpub(self, cmd)
            S.expect(pexpect.EOF)
            for item in flist:
                assert(item in S.before)
                if os.path.exists("%s/.scigest/%s" % (home(), item)):
                    self.fail("%s/.scigest/%s exists and should not" % (home(),
                                                                        item))

            os.environ['SCIGEST_HOME'] = save_sgh
        except:
            tlogger.info('%s * * * FAILED' % my_name())
            raise
        tlogger.info('%-25s PASSED' % my_name())

    # ------------------------------------------------------------------------
    def test_badsgh_deploy(self):
        """
        test_badsgh_deploy: 'ezpub deploy -i dir -r rd -t file' with
        $SCIGEST_HOME set wrongly

        Expected outcome: error message about setting $SCIGEST_HOME
        """
        try:
            save_sgh = os.environ['SCIGEST_HOME']
            os.environ['SCIGEST_HOME'] = "/no/such/dir"

            cmd = "ezpub deploy -i %s -r %s" % (eg_data_dir("arm"),
                                                "tpb.2011.1228.143100")
            S = spawn_ezpub(self, cmd)
            S.expect(pexpect.EOF, catch_tb=False)
            expected = "%s '%s' %s" % ("Please set $SCIGEST_HOME to",
                                       install_dir(),
                                       "and try again")
            assert(expected in S.before)

            os.environ['SCIGEST_HOME'] = save_sgh
        except:
            tlogger.info('%s * * * FAILED' % my_name())
            raise
        tlogger.info('%-25s PASSED' % my_name())

    # ------------------------------------------------------------------------
    def test_badsgh_gen(self):
        """
        test_badsgh_gen: 'ezpub generate -i dir -p proj' with
        $SCIGEST_HOME set wrongly

        Expected outcome: error message about setting $SCIGEST_HOME
        """
        try:
            save_sgh = os.environ['SCIGEST_HOME']
            os.environ['SCIGEST_HOME'] = "/no/such/dir"

            cmd = "ezpub generate -i %s -p %s" % (eg_data_dir("arm"), "test")
            S = spawn_ezpub(self, cmd)
            S.expect(pexpect.EOF, catch_tb=False)
            expected = "Please set $SCIGEST_HOME to '%s' and try again" % install_dir()
            assert(expected in S.before)

            os.environ['SCIGEST_HOME'] = save_sgh
        except:
            tlogger.info('%s * * * FAILED' % my_name())
            raise
        tlogger.info('%-25s PASSED' % my_name())

    # ------------------------------------------------------------------------
    def test_badsgh_help(self):
        """
        test_badsgh_help: 'ezpub help' with $SCIGEST_HOME set wrongly

        Expected outcome: help info displayed
        """
        try:
            save_sgh = os.environ['SCIGEST_HOME']
            os.environ['SCIGEST_HOME'] = "/no/such/dir"

            cmd = "ezpub help"
            S = spawn_ezpub(self, cmd)
            S.expect(pexpect.EOF, catch_tb=False)
            assert("help - show this list" in S.before)
            d = dir(sys.modules["ezpub"])
            for item in d:
                if item.startswith("ez_"):
                    assert("%s - " % item[3:] in S.before)

            os.environ['SCIGEST_HOME'] = save_sgh
        except:
            tlogger.info('%s * * * FAILED' % my_name())
            raise
        tlogger.info('%-25s PASSED' % my_name())

    # ------------------------------------------------------------------------
    def test_badsgh_ingest(self):
        """
        test_badsgh_ingest: 'ezpub ingest' with $SCIGEST_HOME set wrongly

        Expected outcome: error message about setting $SCIGEST_HOME
        """
        try:
            save_sgh = os.environ['SCIGEST_HOME']
            os.environ['SCIGEST_HOME'] = "/no/such/dir"

            cmd = "ezpub ingest"
            S = spawn_ezpub(self, cmd)
            S.expect(pexpect.EOF, catch_tb=False)
            assert("Please set $SCIGEST_HOME to '%s' and try again" % install_dir()
                   in S.before)

            os.environ['SCIGEST_HOME'] = save_sgh
        except:
            tlogger.info('%s * * * FAILED' % my_name())
            raise
        tlogger.info('%-25s PASSED' % my_name())

    # ------------------------------------------------------------------------
    def test_badsgh_lproj(self):
        """
        test_badsgh_lproj: 'ezpub list_projects' with $SCIGEST_HOME
        set incorrectly

        Expected outcome: error message about setting $SCIGEST_HOME
        """
        try:
            save_sgh = os.environ['SCIGEST_HOME']
            os.environ['SCIGEST_HOME'] = "/no/such/dir"

            cmd = "ezpub list_projects"
            S = spawn_ezpub(self, cmd)
            S.expect(pexpect.EOF, catch_tb=False)
            assert("Please set $SCIGEST_HOME to '%s' and try again" % install_dir()
                   in S.before)

            os.environ['SCIGEST_HOME'] = save_sgh
        except:
            tlogger.info('%s * * * FAILED' % my_name())
            raise
        tlogger.info('%-25s PASSED' % my_name())

    # ------------------------------------------------------------------------
    def test_badsgh_lrd(self):
        """
        test_badsgh_lrd: 'ezpub list_reqdirs' with $SCIGEST_HOME set
        to a non existent directory

        Expected outcome: req dirs listed if any
        """
        try:
            save_sgh = os.environ['SCIGEST_HOME']
            os.environ['SCIGEST_HOME'] = "/no/such/dir"

            cmd = "ezpub list_reqdirs"
            S = spawn_ezpub(self, cmd)
            S.expect(pexpect.EOF)
            uname = pwd.getpwuid(os.getuid())[0]
            assert(uname in S.before or "No request directories" in S.before)

            os.environ['SCIGEST_HOME'] = save_sgh
        except:
            tlogger.info('%s * * * FAILED' % my_name())
            raise
        tlogger.info('%-25s PASSED' % my_name())

    # ------------------------------------------------------------------------
    def test_badsgh_publish(self):
        """
        test_badsgh_publish: 'ezpub publish -i dir -p proj' with
        $SCIGEST_HOME set to a non existent directory

        Expected outcome: error message about setting $SCIGEST_HOME
        """
        try:
            save_sgh = os.environ['SCIGEST_HOME']
            os.environ['SCIGEST_HOME'] = "/no/such/dir"

            cmd = "ezpub publish -i %s" % eg_data_dir("cmip5")
            S = spawn_ezpub(self, cmd)
            S.expect(pexpect.EOF, catch_tb=False)
            assert("Please set $SCIGEST_HOME to '%s' and try again"
                   % install_dir() in S.before)

            os.environ['SCIGEST_HOME'] = save_sgh
        except:
            tlogger.info('%s * * * FAILED' % my_name())
            raise
        tlogger.info('%-25s PASSED' % my_name())

    # ------------------------------------------------------------------------
    def test_badsgh_localpub(self):
        """
        test_badsgh_localpub: 'ezpub localpub -i dir -p proj' with
        $SCIGEST_HOME set to non existent directory

        Expected outcome: error message about setting $SCIGEST_HOME
        """
        try:
            save_sgh = os.environ['SCIGEST_HOME']
            os.environ['SCIGEST_HOME'] = "/no/such/dir"

            cmd = "ezpub localpub -i %s" % eg_data_dir('cmip5')
            S = spawn_ezpub(self, cmd)
            S.expect(pexpect.EOF, catch_tb=False)
            assert("Please set $SCIGEST_HOME to '%s' and try again"
                   % install_dir() in S.before)

            os.environ['SCIGEST_HOME'] = save_sgh
        except:
            tlogger.info('%s * * * FAILED' % my_name())
            raise
        tlogger.info('%-25s PASSED' % my_name())

    # ------------------------------------------------------------------------
    def test_badsgh_stage(self):
        """
        test_badsgh_stage: 'ezpub stage -i dir -t xml' with $SCIGEST_HOME set
        wrongly

        Expected outcome: error message about setting $SCIGEST_HOME
        """
        try:
            save_sgh = os.environ['SCIGEST_HOME']
            os.environ['SCIGEST_HOME'] = "/no/such/dir"

            cmd = "ezpub stage -i %s -t %s" % (eg_data_dir("arm"),
                                               eg_xml("stid.xml"))
            S = spawn_ezpub(self, cmd)
            S.expect(pexpect.EOF, catch_tb=False)
            assert("Please set $SCIGEST_HOME to '%s' and try again"
                   % install_dir() in S.before)

            os.environ['SCIGEST_HOME'] = save_sgh
        except:
            tlogger.info('%s * * * FAILED' % my_name())
            raise
        tlogger.info('%-25s PASSED' % my_name())

    # ------------------------------------------------------------------------
    def test_badsgh_unpublish(self):
        """
        test_badsgh_unpublish: 'ezpub unpublish -x foobar.xml' with
        $SCIGEST_HOME set to a non existent directory

        Expected outcome: error message about setting $SCIGEST_HOME
        """
        try:
            save_sgh = os.environ['SCIGEST_HOME']
            os.environ['SCIGEST_HOME'] = "/no/such/dir"

            cmd = "ezpub unpublish -x foobar.xml"
            S = spawn_ezpub(self, cmd)
            S.expect(pexpect.EOF, catch_tb=False)
            assert("Please set $SCIGEST_HOME to '%s' and try again"
                   % install_dir() in S.before)

            os.environ['SCIGEST_HOME'] = save_sgh
        except:
            tlogger.info('%s * * * FAILED' % my_name())
            raise
        tlogger.info('%-25s PASSED' % my_name())

    # ------------------------------------------------------------------------
    def test_badsgh_localunpub(self):
        """
        test_badsgh_localunpub: 'ezpub localunpub -x foobar.xml' with
        $SCIGEST_HOME to a non existent directory

        Expected outcome: error message about setting $SCIGEST_HOME
        """
        try:
            save_sgh = os.environ['SCIGEST_HOME']
            os.environ['SCIGEST_HOME'] = "/no/such/dir"

            cmd = "ezpub localunpub -x foobar.xml"
            S = spawn_ezpub(self, cmd)
            S.expect(pexpect.EOF, catch_tb=False)
            self.assertEqual("Please set $SCIGEST_HOME to '%s' and try again"
                             % install_dir() in S.before, True)

            os.environ['SCIGEST_HOME'] = save_sgh
        except:
            tlogger.info('%s * * * FAILED' % my_name())
            raise
        tlogger.info('%-25s PASSED' % my_name())

    # ------------------------------------------------------------------------
    def test_nosgh_cleanup(self):
        """
        test_nosgh_cleanup: 'ezpub cleanup' with $SCIGEST_HOME unset

        Expected outcome: $HOME/.scigest cleaned up
        """
        try:
            save_sgh = os.environ['SCIGEST_HOME']
            del os.environ['SCIGEST_HOME']

            # this is the list of things to be removed
            flist = [os.path.basename(x)
                     for x in glob.glob("%s/.scigest/*" % home())]

            # except for these
            rlist = ["catalog.xml", "my.properties", "my.properties~"]
            for item in rlist:
                if item in flist: flist.remove(item)

            cmd = "ezpub cleanup"
            S = spawn_ezpub(self, cmd)
            S.expect(pexpect.EOF)
            for item in flist:
                assert(item in S.before)
                if os.path.exists("%s/.scigest/%s" % (home(), item)):
                    self.fail("%s/.scigest/%s exists and should not" % (home(),
                                                                        item))

            os.environ['SCIGEST_HOME'] = save_sgh
        except:
            tlogger.info('%s * * * FAILED' % my_name())
            raise
        tlogger.info('%-25s PASSED' % my_name())

    # ------------------------------------------------------------------------
    def test_nosgh_deploy(self):
        """
        test_nosgh_deploy: 'ezpub deploy -i dir -r rd -t file' with
        $SCIGEST_HOME unset

        Expected outcome: error message about setting $SCIGEST_HOME
        """
        try:
            save_sgh = os.environ['SCIGEST_HOME']
            del os.environ['SCIGEST_HOME']

            cmd = "ezpub deploy -i %s -r %s" % (eg_data_dir("arm"),
                                                "tpb.2011.1228.143100")
            S = spawn_ezpub(self, cmd)
            S.expect(pexpect.EOF, catch_tb=False)
            assert("Please set $SCIGEST_HOME to '%s' and try again" % install_dir()
                   in S.before)

            os.environ['SCIGEST_HOME'] = save_sgh
        except:
            tlogger.info('%s * * * FAILED' % my_name())
            raise
        tlogger.info('%-25s PASSED' % my_name())

    # ------------------------------------------------------------------------
    def test_nosgh_gen(self):
        """
        test_nosgh_gen: 'ezpub generate -i dir -p proj' with
        $SCIGEST_HOME unset

        Expected outcome: error message about setting $SCIGEST_HOME
        """
        try:
            save_sgh = os.environ['SCIGEST_HOME']
            del os.environ['SCIGEST_HOME']

            cmd = "ezpub generate -i %s -p %s" % (eg_data_dir("arm"), "test")
            S = spawn_ezpub(self, cmd)
            S.expect(pexpect.EOF, catch_tb=False)
            assert("Please set $SCIGEST_HOME to '%s' and try again" % install_dir()
                   in S.before)

            os.environ['SCIGEST_HOME'] = save_sgh
        except:
            tlogger.info('%s * * * FAILED' % my_name())
            raise
        tlogger.info('%-25s PASSED' % my_name())

    # ------------------------------------------------------------------------
    def test_nosgh_help(self):
        """
        test_nosgh_help: 'ezpub help' with $SCIGEST_HOME unset

        Expected outcome: help info displayed
        """
        try:
            save_sgh = os.environ['SCIGEST_HOME']
            del os.environ['SCIGEST_HOME']

            cmd = "ezpub help"
            S = spawn_ezpub(self, cmd)
            S.expect(pexpect.EOF)
            assert("help - show this list" in S.before)
            d = dir(sys.modules["ezpub"])
            for item in d:
                if item.startswith("ez_"):
                    assert("%s - " % item[3:] in S.before)

            os.environ['SCIGEST_HOME'] = save_sgh
        except:
            tlogger.info('%s * * * FAILED' % my_name())
            raise
        tlogger.info('%-25s PASSED' % my_name())

    # ------------------------------------------------------------------------
    def test_nosgh_ingest(self):
        """
        test_nosgh_ingest: 'ezpub ingest' with $SCIGEST_HOME unset

        Expected outcome: error message about setting $SCIGEST_HOME
        """
        try:
            save_sgh = os.environ['SCIGEST_HOME']
            del os.environ['SCIGEST_HOME']

            cmd = "ezpub ingest"
            S = spawn_ezpub(self, cmd)
            S.expect(pexpect.EOF, catch_tb=False)
            assert("Please set $SCIGEST_HOME to '%s' and try again" % install_dir()
                   in S.before)

            os.environ['SCIGEST_HOME'] = save_sgh
        except:
            tlogger.info('%s * * * FAILED' % my_name())
            raise
        tlogger.info('%-25s PASSED' % my_name())

    # ------------------------------------------------------------------------
    def test_nosgh_lproj(self):
        """
        test_nosgh_lproj: 'ezpub list_projects' with $SCIGEST_HOME unset

        Expected outcome: error message about setting $SCIGEST_HOME
        """
        try:
            save_sgh = os.environ['SCIGEST_HOME']
            del os.environ['SCIGEST_HOME']

            cmd = "ezpub list_projects"
            S = spawn_ezpub(self, cmd)
            S.expect(pexpect.EOF, catch_tb=False)
            assert("Please set $SCIGEST_HOME to '%s' and try again" % install_dir()
                   in S.before)

            os.environ['SCIGEST_HOME'] = save_sgh
        except:
            tlogger.info('%s * * * FAILED' % my_name())
            raise
        tlogger.info('%-25s PASSED' % my_name())

    # ------------------------------------------------------------------------
    def test_nosgh_lrd(self):
        """
        test_nosgh_lrd: 'ezpub list_reqdirs' with $SCIGEST_HOME unset

        Expected outcome: req dirs listed if any
        """
        try:
            save_sgh = os.environ['SCIGEST_HOME']
            del os.environ['SCIGEST_HOME']

            cmd = "ezpub list_reqdirs"
            S = spawn_ezpub(self, cmd)
            S.expect(pexpect.EOF)
            uname = pwd.getpwuid(os.getuid())[0]
            assert(uname in S.before or "No request directories" in S.before)

            os.environ['SCIGEST_HOME'] = save_sgh
        except:
            tlogger.info('%s * * * FAILED' % my_name())
            raise
        tlogger.info('%-25s PASSED' % my_name())

    # ------------------------------------------------------------------------
    def test_nosgh_publish(self):
        """
        test_nosgh_publish: 'ezpub publish -i dir -p proj' with
        $SCIGEST_HOME unset

        Expected outcome: error message about setting $SCIGEST_HOME
        """
        try:
            save_sgh = os.environ['SCIGEST_HOME']
            del os.environ['SCIGEST_HOME']

            cmd = "ezpub publish -i %s" % eg_data_dir("test")
            S = spawn_ezpub(self, cmd)
            S.expect(pexpect.EOF, catch_tb=False)
            assert("Please set $SCIGEST_HOME to '%s' and try again" % install_dir()
                   in S.before)

            os.environ['SCIGEST_HOME'] = save_sgh
        except:
            tlogger.info('%s * * * FAILED' % my_name())
            raise
        tlogger.info('%-25s PASSED' % my_name())

    # ------------------------------------------------------------------------
    def test_nosgh_localpub(self):
        """
        test_nosgh_localpub: 'ezpub localpub -i dir -p proj' with
        $SCIGEST_HOME unset

        Expected outcome: error message about setting $SCIGEST_HOME
        """
        try:
            save_sgh = os.environ['SCIGEST_HOME']
            del os.environ['SCIGEST_HOME']

            cmd = "ezpub localpub -i %s" % eg_data_dir("test")
            S = spawn_ezpub(self, cmd)
            S.expect(pexpect.EOF, catch_tb=False)
            assert("Please set $SCIGEST_HOME to '%s' and try again"
                   % install_dir() in S.before)

            os.environ['SCIGEST_HOME'] = save_sgh
        except:
            tlogger.info('%s * * * FAILED' % my_name())
            raise
        tlogger.info('%-25s PASSED' % my_name())

    # ------------------------------------------------------------------------
    def test_nosgh_stage(self):
        """
        test_nosgh_stage: 'ezpub stage -i dir -x xml' with $SCIGEST_HOME unset

        Expected outcome: error message about setting $SCIGEST_HOME
        """
        try:
            save_sgh = os.environ['SCIGEST_HOME']
            del os.environ['SCIGEST_HOME']

            cmd = "ezpub stage -i %s -t %s" % (eg_data_dir("c-lamp"),
                                               eg_xml("std.xml"))
            S = spawn_ezpub(self, cmd)
            S.expect(pexpect.EOF, catch_tb=False)
            assert("Please set $SCIGEST_HOME to '%s' and try again"
                   % install_dir() in S.before)
            os.environ['SCIGEST_HOME'] = save_sgh
        except:
            tlogger.info('%s * * * FAILED' % my_name())
            raise
        tlogger.info('%-25s PASSED' % my_name())

    # ------------------------------------------------------------------------
    def test_nosgh_unpublish(self):
        """
        test_nosgh_unpublish: 'ezpub unpublish -x foobar.xml' with
        $SCIGEST_HOME unset

        Expected outcome: error message about setting $SCIGEST_HOME
        """
        try:
            save_sgh = os.environ['SCIGEST_HOME']
            del os.environ['SCIGEST_HOME']

            cmd = "ezpub unpublish -x frooble.xml"
            S = spawn_ezpub(self, cmd)
            S.expect(pexpect.EOF, catch_tb=False)
            assert("Please set $SCIGEST_HOME to '%s' and try again"
                   % install_dir() in S.before)
            os.environ['SCIGEST_HOME'] = save_sgh
        except:
            tlogger.info('%s * * * FAILED' % my_name())
            raise
        tlogger.info('%-25s PASSED' % my_name())

    # ------------------------------------------------------------------------
    def test_nosgh_localunpub(self):
        """
        test_nosgh_localunpub: 'ezpub localunpub -x foobar.xml' with
        $SCIGEST_HOME unset

        Expected outcome: error message about setting $SCIGEST_HOME
        """
        try:
            save_sgh = os.environ['SCIGEST_HOME']
            del os.environ['SCIGEST_HOME']

            cmd = "ezpub localunpub -x frooble.xml"
            S = spawn_ezpub(self, cmd)
            S.expect(pexpect.EOF, catch_tb=False)
            assert("Please set $SCIGEST_HOME to '%s' and try again"
                   % install_dir() in S.before)
            os.environ['SCIGEST_HOME'] = save_sgh
        except:
            tlogger.info('%s * * * FAILED' % my_name())
            raise
        tlogger.info('%-25s PASSED' % my_name())

    # ------------------------------------------------------------------------
    def test_nohom_cleanup(self):
        """
        test_nohom_cleanup: 'ezpub cleanup' with $HOME unset

        Expected outcome: error about setting $HOME
        """
        try:
            save_home = os.environ['HOME']
            del os.environ['HOME']

            cmd = "ezpub cleanup"
            S = spawn_ezpub(self, cmd)
            S.expect(pexpect.EOF, catch_tb=False)
            assert("Please set $HOME and try again")

            os.environ['HOME'] = save_home
        except:
            tlogger.info('%s * * * FAILED' % my_name())
            raise
        tlogger.info('%-25s PASSED' % my_name())

    # ------------------------------------------------------------------------
    def test_nohom_deploy(self):
        """
        test_nohom_deploy: 'ezpub deploy -i dir -r rd -t file' with
        $HOME unset

        Expected outcome: error message about setting $HOME
        """
        try:
            save_home = os.environ['HOME']
            del os.environ['HOME']

            cmd = "ezpub deploy"
            S = spawn_ezpub(self, cmd)
            S.expect(pexpect.EOF, catch_tb=False)
            assert("Please set $HOME and try again")

            os.environ['HOME'] = save_home
        except:
            tlogger.info('%s * * * FAILED' % my_name())
            raise
        tlogger.info('%-25s PASSED' % my_name())

    # ------------------------------------------------------------------------
    def test_nohom_gen(self):
        """
        test_nohom_gen: 'ezpub generate -i dir -p proj' with $HOME unset

        Expected outcome: error message about setting $HOME
        """
        try:
            save_home = os.environ['HOME']
            del os.environ['HOME']

            cmd = "ezpub generate -i %s -p test" % eg_data_dir("arm")
            S = spawn_ezpub(self, cmd)
            S.expect(pexpect.EOF, catch_tb=False)
            assert("Please set $HOME and try again")

            os.environ['HOME'] = save_home
        except:
            tlogger.info('%s * * * FAILED' % my_name())
            raise
        tlogger.info('%-25s PASSED' % my_name())

    # ------------------------------------------------------------------------
    def test_nohom_help(self):
        """
        test_nohom_help: 'ezpub help' with $HOME unset

        Expected outcome: help info displayed
        """
        try:
            save_home = os.environ['HOME']
            del os.environ['HOME']

            cmd = "ezpub help"
            S = spawn_ezpub(self, cmd)
            S.expect(pexpect.EOF)
            assert("help - show this list" in S.before)
            d = dir(sys.modules["ezpub"])
            for item in d:
                if item.startswith("ez_"):
                    assert("%s - " % item[3:] in S.before)

            os.environ['HOME'] = save_home
        except:
            tlogger.info('%s * * * FAILED' % my_name())
            raise
        tlogger.info('%-25s PASSED' % my_name())

    # ------------------------------------------------------------------------
    def test_nohom_ingest(self):
        """
        test_nohom_ingest: 'ezpub ingest' with $HOME unset

        Expected outcome: error message about setting $HOME
        """
        try:
            save_home = os.environ['HOME']
            del os.environ['HOME']

            cmd = "ezpub ingest"
            S = spawn_ezpub(self, cmd)
            S.expect(pexpect.EOF, catch_tb=False)
            assert("Please set $HOME and try again" in S.before)

            os.environ['HOME'] = save_home
        except:
            tlogger.info('%s * * * FAILED' % my_name())
            raise
        tlogger.info('%-25s PASSED' % my_name())

    # ------------------------------------------------------------------------
    def test_nohom_lproj(self):
        """
        test_nohom_lproj: 'ezpub list_projects' with $HOME unset

        Expected outcome: list projects
        """
        try:
            save_home = os.environ['HOME']
            del os.environ['HOME']

            cmd = "ezpub list_projects"
            S = spawn_ezpub(self, cmd)
            S.expect(pexpect.EOF, catch_tb=False)
            assert("Available Projects:" in S.before)
            for proj in ezp_cfg.project_list():
                assert(proj in S.before)

            os.environ['HOME'] = save_home
        except:
            tlogger.info('%s * * * FAILED' % my_name())
            raise
        tlogger.info('%-25s PASSED' % my_name())

    # ------------------------------------------------------------------------
    def test_nohom_lrd(self):
        """
        test_nohom_lrd: 'ezpub list_reqdirs' with $HOME unset

        Expected outcome: list req dirs
        """
        try:
            save_home = os.environ['HOME']
            del os.environ['HOME']

            cmd = "ezpub list_reqdirs"
            S = spawn_ezpub(self, cmd)
            S.expect(pexpect.EOF)
            uname = pwd.getpwuid(os.getuid())[0]
            assert(uname in S.before or "No request directories" in S.before)

            os.environ['HOME'] = save_home
        except:
            tlogger.info('%s * * * FAILED' % my_name())
            raise
        tlogger.info('%-25s PASSED' % my_name())

    # ------------------------------------------------------------------------
    def test_nohom_publish(self):
        """
        test_nohom_publish: 'ezpub publish -i dir -p proj' with
        $HOME unset

        Expected outcome: error message about setting $HOME
        """
        try:
            save_home = os.environ['HOME']
            del os.environ['HOME']

            cmd = "ezpub publish -i %s -p test" % eg_data_dir("test")
            S = spawn_ezpub(self, cmd)
            S.expect(pexpect.EOF, catch_tb=False)
            assert("Please set $HOME and try again" in S.before)

            os.environ['HOME'] = save_home
        except:
            tlogger.info('%s * * * FAILED' % my_name())
            raise
        tlogger.info('%-25s PASSED' % my_name())

    # ------------------------------------------------------------------------
    def test_nohom_localpub(self):
        """
        test_nohom_localpub: 'ezpub localpub -i dir -p proj' with
        $HOME unset

        Expected outcome: error message about setting $HOME
        """
        try:
            save_home = os.environ['HOME']
            del os.environ['HOME']

            cmd = "ezpub localpub -i %s -p test" % eg_data_dir('test')
            S = spawn_ezpub(self, cmd)
            S.expect(pexpect.EOF, catch_tb=False)
            assert("Please set $HOME and try again" in S.before)

            os.environ['HOME'] = save_home
        except:
            tlogger.info('%s * * * FAILED' % my_name())
            raise
        tlogger.info('%-25s PASSED' % my_name())

    # ------------------------------------------------------------------------
    def test_nohom_stage(self):
        """
        test_nohom_stage: 'ezpub stage -i dir -t xml' with $HOME unset

        Expected outcome: error message about setting $HOME
        """
        try:
            save_home = os.environ['HOME']
            del os.environ['HOME']

            cmd = "ezpub stage -i %s -t %s" % (eg_data_dir("cmip5"),
                                               eg_xml("stid.xml"))
            S = spawn_ezpub(self, cmd)
            S.expect(pexpect.EOF, catch_tb=False)
            assert("Please set $HOME and try again" in S.before)

            os.environ['HOME'] = save_home
        except:
            tlogger.info('%s * * * FAILED' % my_name())
            raise
        tlogger.info('%-25s PASSED' % my_name())

    # ------------------------------------------------------------------------
    def test_nohom_unpublish(self):
        """
        test_nohom_unpublish: 'ezpub unpublish -x foobar.xml' with
        $HOME unset

        Expected outcome: error message about setting $HOME
        """
        try:
            save_home = os.environ['HOME']
            del os.environ['HOME']

            cmd = "ezpub unpublish -x foobar.xml"
            S = spawn_ezpub(self, cmd)
            S.expect(pexpect.EOF, catch_tb=False)
            assert("Please set $HOME and try again" in S.before)

            os.environ['HOME'] = save_home
        except:
            tlogger.info('%s * * * FAILED' % my_name())
            raise
        tlogger.info('%-25s PASSED' % my_name())

    # ------------------------------------------------------------------------
    def test_nohom_localunpub(self):
        """
        test_nohom_localunpub: 'ezpub localunpub -x foobar.xml' with
        $HOME unset

        Expected outcome: error message about setting $HOME
        """
        try:
            save_home = os.environ['HOME']
            del os.environ['HOME']

            cmd = "ezpub localunpub -x foobar.xml"
            S = spawn_ezpub(self, cmd)
            S.expect(pexpect.EOF, catch_tb=False)
            assert("Please set $HOME and try again" in S.before)
            os.environ['HOME'] = save_home
        except:
            tlogger.info('%s * * * FAILED' % my_name())
            raise
        tlogger.info('%-25s PASSED' % my_name())

    # ------------------------------------------------------------------------
    def test_nodot_pclok(self):
        """
        test_nodot_pclok: generate a thredds file

        Expected outcome: error message about setting $SCIGEST_HOME
        """
        try:
            scigest_build_check(self)
            pcfg = "%s/.scigest" % home()
            if os.path.exists(pcfg):
                shutil.rmtree(pcfg)
            project = 'test'
            section = 'project:%s' % project
            input_dir = eg_data_dir(project)
            cmd = "ezpub generate --project %s --input %s" % (project,
                                                              input_dir)
            cfg = ezp_cfg.loadConfig("./esg.ini")
            cfg.set(section, 'project', project)
            S = spawn_ezpub(self, cmd)
            S.expect(pexpect.EOF)
            self.verify_generation(S, input_dir, project)
        except:
            tlogger.info('%s * * * FAILED' % my_name())
            raise
        tlogger.info('%-25s PASSED' % my_name())

    # ------------------------------------------------------------------------
    def test_nodot_cleanup(self):
        """
        test_nodot_cleanup: 'ezpub cleanup' when $HOME/.scigest does not exist

        Expected outcome: message -- 'Nothing to clean up.'
        """
        try:
            pcfg = "%s/.scigest" % home()
            if os.path.exists(pcfg):
                shutil.rmtree(pcfg)
            project = 'test'
            cmd = "ezpub cleanup"
            S = spawn_ezpub(self, cmd)
            S.expect(pexpect.EOF)
            assert("Nothing to clean up." in S.before)
        except:
            tlogger.info('%s * * * FAILED' % my_name())
            raise
        tlogger.info('%-25s PASSED' % my_name())

    # ------------------------------------------------------------------------
    def txst_xmd_gen(self):
        """
        test_xmd_gen: 'ezpub generate -i dir -p proj -m xmdfile'

        Expected outcome: thredds file generated, xmdfile ready for stage
        """
        try:
            scigest_build_check(self)
            project = 'test'
            section = 'project:%s' % project
            input_dir = eg_data_dir(project)
            cmd = "ezpub generate -p %s -i %s -m readme.md" % (project, input_dir)
            cfg = ezp_cfg.loadConfig("./esg.ini")
            cfg.set(section, 'project', project)
            S = spawn_ezpub(self, cmd)
            S.expect(pexpect.EOF)
            self.verify_generation(S, input_dir, project)
        except:
            tlogger.info('%s * * * FAILED' % my_name())
            raise
        tlogger.info('%-25s PASSED' % my_name())

    # ------------------------------------------------------------------------
    def verify_generation(self, S, dirpath, project, suffix=None):
        assert("scigest" in S.before)
        if suffix == None:
            suffix = os.path.basename(dirpath)
        xmlpath = "%s/.scigest/output/1/%s_%s.xml" % (home(), project, suffix)
        catalog_txt = "%s/.scigest/catalog.txt" % (home())
        assert(os.path.exists(xmlpath))
        filename = os.path.basename(xmlpath)
        assert(filename in contents(catalog_txt))
        assert(datafiles_in_xml(dirpath, xmlpath))

# ---------------------------------------------------------------------------
def check_environment():
    """
    Look at the runtime environment (current directory and
    $SCIGEST_HOME setting) to decide whether the tests can be run
    meaningfully.
    """
    if scigest_home() != install_dir():
        print("To run these tests, please set")
        print("export SCIGEST_HOME=%s" % install_dir())
        os.sys.exit(1)

    rundir = "%s/ezpub" % scigest_home()
    loc = autofs_to_ccs(os.getcwd())
    if rundir != loc:
        print("To run these tests, please")
        print("cd %s" % rundir)
        os.sys.exit(1)

    path = "./ezpub"
    if not os.path.exists(path):
        os.symlink("./ezpub.py", path)
    elif not os.path.islink(path):
        print("%s should be a link to ./ezpub.py but it isn't." % path)
        os.sys.exit(1)
        
    pypath = os.getenv('PYTHONPATH')
    if pypath == None or 'ezpub' not in pypath:
        os.environ['PYTHONPATH'] = os.getenv('SCIGEST_HOME') + '/ezpub'

# ---------------------------------------------------------------------------
def datafiles_in_xml(dir, xmlpath):
    """
    The data files in dir should be mentioned in the XML file at
    xmlpath. If any are missing, return False. If they are all there,
    return True.
    """
    files = [os.path.basename(x) for x in glob.glob("%s/*" % dir)]
    xml = contents(xmlpath)
    for filename in files:
        if filename not in xml:
            return False
    return True

# ---------------------------------------------------------------------------
def eg_data_dir(project):
    """
    Find and return the path to a directory of test data.
    """
    if os.path.isdir("./testdata/nc"):
        input_dir = "./testdata/nc/%s" % project
    else:
        try:
            dataroot = os.environ['EZPUB_TEST_DATA']
            input_dir = "%s/nc/%s" % (dataroot, project)
        except:
            print("Test data directory not found. Please set $EZPUB_TEST_DATA.")
            sys.exit(1)
    return input_dir
        
# ---------------------------------------------------------------------------
def eg_xml(filename):
    """
    Find and return the path to a directory of test XML data.
    """
    if os.path.isdir("./testdata/xml"):
        rval = "./testdata/xml/%s" % filename
    else:
        try:
            dataroot = os.path.dirname(os.environ['EZPUB_TEST_DATA'])
            rval = "%s/%s/%s" % (dataroot, "xml", filename)
        except:
            print("XML data directory not found. Please set $EZPUB_TEST_DATA.")
            sys.exit(1)
    return rval

# ---------------------------------------------------------------------------
def home():
    """
    Return the setting of $HOME.
    """
    return os.environ['HOME']

# ---------------------------------------------------------------------------
def isrunnable(cmd):
    """
    If the program mentioned in cmd is runnable, return True, else False.
    """
    path = os.getenv("PATH")
    for pc in path.split(":"):
        fpath = os.path.join(pc, cmd)
        if os.access(fpath, os.X_OK):
            return True
    return False
        
# ---------------------------------------------------------------------------
def make_app_prop(project='test', datasrc=''):
    """
    Write a minimal application.properties file in $HOME/.scigest.
    """
    path = "%s/.scigest/application.properties" % home()
    if not os.path.exists(path):
        f = open(path, 'w')
        f.write("# written by ezpub_tests.make_app_prop\n")
        if datasrc != '':
            f.write("data.src = %s\n" % datasrc)
        f.write("data.path = esg_dataroot\n")
        f.write("data.location = /esg/data\n")
        f.write("data.layout = flat\n")
        f.write("project.name = clm_single\n")
        f.close()

# ---------------------------------------------------------------------------
def make_dir_xml(dirname, filename):
    """
    Test setup: create an empty directory dirname and a dummy xml file
    filename.
    """
    if os.path.exists(dirname):
        os.rmdir(dirname)
    os.mkdir(dirname)
    make_dummy_xml(filename)
    
# ---------------------------------------------------------------------------
def make_dummy_xml(filename):
    """
    Create an XML file to have something to test against.
    """
    f = open(filename, "w")
    f.write('<?xml version="1.0" encoding="UTF-8"?>\n')
    f.write('<catalog'
            + ' xmlns="http://www.unidata.ucar.edu/namespaces/thredds'
            + '/InvCatalog/v1.0"'
            + ' xmlns:xlink="http://www.w3.org/1999/xlink"'
            + ' xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"'
            + ' xsi:schemaLocation="http://www.unidata.ucar.edu/namespaces'
            + '/thredds/InvCatalog/v1.0'
            + ' http://www.unidata.ucar.edu/schemas/thredds/InvCatalog.1.0.2.xsd"'
            + ' name="TDS Configuration File" version="1.0.1">\n')
    f.write('  <service name="HTTPServer" serviceType="HTTPServer"'
            + ' base="/thredds/fileServer/">\n')
    f.write('    <property name="requires_authorization" value="true" />\n')
    f.write('    <property name="application" value="Web Browser" />\n')
    f.write('    <property name="application" value="Web Script" />\n')
    f.write('  </service>\n')
    f.write('  <property name="catalog_version" value="2" />\n')
    f.write('  <dataset name="ornl.test.clm_flat" ID="ornl.test.clm_flat.v1"'
            + ' restrictAccess="esg-user">\n')
    f.write('  </dataset>\n')
    f.write('</catalog>\n')
    f.close()
    
# ---------------------------------------------------------------------------
def remove_dir_xml(dirname, filename):
    """
    Cleanup dirname and filename by removing them. This will fail if
    dirname is not empty.
    """
    os.rmdir(dirname)
    os.unlink(filename)

# ---------------------------------------------------------------------------
def safe_mkdir(dirname):
    """
    After running this, we should have a brand new, empty directory
    called dirname.
    """
    if os.path.isdir(dirname):
        os.rmdir(dirname)
    os.mkdir(dirname)
    
# ---------------------------------------------------------------------------
def scigest_build_check(caller):
    """
    Check whether scigest has been built so tests can be run meaningfully.
    """
    catgen_path = "%s/build/scigest/core/CatalogGen.class" % scigest_home()
    scijar_glob = glob.glob("%s/lib/scigest-*.jar" % scigest_home())
    if 0 < len(scijar_glob):
        scijar_path = scijar_glob[-1]
    else:
        "nosuchfile"
    try:
        assert(os.path.exists(catgen_path) or os.path.exists(scijar_path))
    except:
        caller.fail("""Please build scigest and try again:

        cd ..
        ant build
        cd ezpub
        ezpub_tests
        """)

# ---------------------------------------------------------------------------
def setup_logging():
    global tlogger

    tlogger = logging.getLogger('Ezpub')
    tlogger.setLevel(logging.INFO)

    hostname = socket.gethostname().split('.')[0]
    fh = logging.handlers.RotatingFileHandler("./ezpub_tests.log",
                                              maxBytes=10*1024*1024,
                                              backupCount=5)
    strfmt = "%" + "(asctime)s [%s] " % hostname + "%" + "(message)s"
    fmt = logging.Formatter(strfmt, datefmt="%Y.%m%d %H:%M:%S")
    fh.setFormatter(fmt)

    tlogger.addHandler(fh)
    tlogger.info('-' * (55 - len(hostname)))
    
# ---------------------------------------------------------------------------
def show_stdout(value=None):
    """
    Return value of global value show_stdout. Optionally set it if
    value is specified. If it is not set, the default return value is False.
    """
    global show_output
    try:
        rval = show_output
    except:
        rval = False
        
    if value != None:
        show_output = value
        
    return rval

# -----------------------------------------------------------------------
def skip_disclaimer_yes():
    """
    Determine whether to run or skip test_disclaimer_yes.
    """
    return not isrunnable("modulecmd")
    
# -----------------------------------------------------------------------
def skip_disclaimer_YES():
    """
    Determine whether to run or skip test_disclaimer_YES.
    """
    return not isrunnable("modulecmd")
    
# ---------------------------------------------------------------------------
def spawn_ezpub(caller, cmd):
    """
    Fire up ezpub by passing cmd to the EzpubSpawn constructor to get
    an slightly enhanced pexpect spawn object.
    """
    return EzpubSpawn(cmd, show_stdout())

# ---------------------------------------------------------------------------
def touch(filename):
    """
    Do the same thing as the command touch(1).
    """
    open(filename, 'a').close()

# ---------------------------------------------------------------------------
# This is used by several tests above.
strings = ['one', 'two', 'three', 'four', 'five']

# ---------------------------------------------------------------------------
if __name__ == '__main__':
    main(sys.argv)
